/*
 * queue.h
 *
 *  Created on: Sep 13, 2012
 *      Author: arun
 */

#ifndef QUEUE_H_
#define QUEUE_H_

#include <stdio.h>
#include <stdlib.h>

#define INFINITE 100000


struct item
{
	long id;
	long arrival_time;
	long service_start_time;
	long service_time;
	long service_end_time;
};

struct queue_t
{
	struct item* queue;
	long add_index;
	long remove_index;
	long size;
	long count;
};

void create_queue(struct queue_t *q, long size = INFINITE){
	try{
		if(q->queue == NULL){
			q->queue = (struct item*) malloc (sizeof(struct item) * size);
		}
		q->add_index = 0;
		q->remove_index = 0;
		q->size = size;
		q->count = 0;
	}
	catch(...)
	{
		printf("Error! Unable to allocate memory for queue!");
		exit(-1);
	}

}

int enqueue(struct queue_t *q, struct item data){
	if(q->count == q->size)
	{ // Queue full - packet dropped
		return -1;
	}
	else
	{
		q->queue[q->add_index] = data;
		q->add_index = (q->add_index + 1) % q->size;
		q->count += 1;
		return 0;
	}
}

struct item dequeue(struct queue_t *q){
	struct item return_data;
	if(q->count == 0){
		// Nothing to dequeue
		return_data.id = -1;
	}
	else
	{
		return_data = q->queue[q->remove_index];
		q->remove_index = (q->remove_index + 1) % q->size;
		q->count--;
	}
	return return_data;
}

void sort_queue(struct queue_t *q){
	int i,j;
	for(i = q->remove_index; i < q->remove_index + q->count; ++i)
	{
		for(j = q->remove_index; j < q->remove_index + q->count - i - 1; ++j){
			if(q->queue[j%q->size].service_end_time > q->queue[(j+1)%q->size].service_end_time)
			{
				struct item temp = q->queue[j%q->size];
				q->queue[j%q->size] =  q->queue[(j+1)%q->size];
				 q->queue[(j+1)%q->size] = temp;
			}
		}
	}
}

void print_queue(struct queue_t *q){
	printf("Queue Contents:");
	for(int i = q->remove_index; i < q->remove_index + q->count; ++i){
		printf(" %ld ", q->queue[i%q->size].id);
	}
	printf("\n");
}


#endif /* QUEUE_H_ */
